import type { ValidateFieldsError } from 'async-validator';

export type Overwrite<T, K extends keyof T, V> = {
  [P in K]: V;
} & Omit<T, K>;

export interface DataObject<V = unknown> {
  [key: string]: V;
}

export type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

export type RecursivePartial<T> = {
  [P in keyof T]?: T[P] extends (infer U)[]
    ? RecursivePartial<U>[]
    : T[P] extends unknown
    ? RecursivePartial<T[P]>
    : T[P];
};

export type DeepRequired<T> = {
  [P in keyof T]-?: T[P] extends (infer U)[] | undefined
    ? DeepRequired<U>[]
    : T[P] extends unknown | undefined
    ? DeepRequired<T[P]>
    : T[P];
};

export type PartialRecord<K extends keyof unknown, T> = Partial<Record<K, T>>;

//Element Plus

export interface FormCallback {
  (isValid?: boolean, invalidFields?: ValidateFieldsError): void;
}

export type FormItemValidateCallback = (msg?: string | Error) => void;

export type FormItemValidate = (rule: unknown, value: string, callback: FormItemValidateCallback) => void;

export type FormRules = Record<string, unknown>;

export interface ELForm {
  validate: (callback?: FormCallback) => Promise<boolean>;
}

export interface ELTree {
  setCheckedKeys: (keys: unknown[], leafOnly?: boolean) => Promise<boolean>;
  getCheckedNodes: (leafOnly?: boolean, includeHalfChecked?: boolean) => unknown[];
}

export interface ELInput {
  focus: () => void;
}

export interface ElUploadRequestOptions {
  action: string;
  method: string;
  data: Record<string, string | Blob>;
  filename: string;
  file: File;
  headers: Headers;
  onError: (e: Error) => void;
  onProgress: (e: ProgressEvent) => void;
  onSuccess: (response: XMLHttpRequestResponseType) => unknown;
  withCredentials: boolean;
}
